package com.asa.group;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * 需要先保证传入的集合是个群
 * 循环群
 * 群的循环群/群的循环子群
 * 也有叫
 * 乘群的循环群/乘群的循环子群
 * 因为一般来说是乘法满足这个条件
 * 
 * 
 * 定义很复杂，因为它要考虑无限群，这里默认只用考虑有限群，问题变简单很多了
 * 
 * 
 * 定义1. （循环群）设 G 是群。若存在 a属于G ，使得对任意b属于G  ，存在n是整数  ，满足a^n=b  。
 * 则称 G 是循环群。称 a 为循环群 G 的生成元。
 * 
 * 通俗点说就是在群里面挑选元素，保证该元素能通过不断的自己与自己进行运算从而表达出整个群里面的元素。如果我们能
 * 在群中找到这样的元素，那么这个群就是循环群了
 * 
 * 
 * 这里的n不单指乘法，抽象的推广来说应该是计算了n次
 * 
 * 
 * @author asa
 * 
 * 
 * 很多时候不是通过群去找它得生成元
 * 现实中很多时候是我们找到一个生成元，用生成元得到了一个循环群
 * 
 * 循环群是abel群
 * 
 *
 */
public class GroupCycle {
	
	
	
	/**
	 * 需要先确保list是群
	 * 找到a来判断是否是循环群
	 * 这里是专门针对有限群的，那么有限群就有一个性质，如果是循环群那么a^n=b中的n是list的长度，而且n为非负整数
	 * 有限群必然是循环群
	 * @param <T>
	 * @param list
	 * @param func
	 */
	public static<T> ArrayList<T> findA(ArrayList<T> list,ObjectFunction<T> func) {
		ArrayList<T> result = new ArrayList<>();
		
		for (int i = 0; i < list.size(); i++) {//O(n*n)的时间复杂度，应该可以对算法进行优化
			T t = list.get(i);
			
			T asa = t;
			ArrayList<T> buffer = new ArrayList<T>();
			buffer.add(asa);
			
			
			for (int j = 0; j < list.size(); j++) {
				asa = func.hanshu(asa, t);

				if (buffer.contains(asa)) {
					break;
				}else {
					buffer.add(asa);

				}
				
				
			}
			
			if (buffer.size()==list.size()) {
				result.add(t);
			}
			
		}
		
		return result;
		
		
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * 
	 * 定义2.（群中元素的阶，群的方次数）设 G 是群， e 是 G 的单位元。

		（1）若存在 n属于不等于0的自然数 ，使得a^n=e  ，则称使得a^n = e  成立的最小的正整数 n 为元素 a 的阶，记作 |a| 。
		
		（2）若对任意 n属于不等于0的自然数 ， a^n!=e ，则称 a 的阶为 无穷（♾️） ，记作 |a|=♾️ 。
		
		（3）exp(G) =t ，其中t为 a^t=e，其中a属于G，并且对a进行选择，使得t最小	t可能是无穷的	这个写法不是很严谨
	 * 
	 * 
	 */
	public static<T> int findN(ArrayList<T> list,ObjectFunction<T> fun,T e) {
		
		
		
		
		
		//秀得很
		return list.size();
		
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * 
	 * 定义3. 对于群 G=<a> ，若 |a|=♾️ ，则称 G 为无限阶循环群；若 |a|<♾️ ，则称 G 是有限阶循环群。
	 */
	
	
	
	
	

}
